package com.hosever.core;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;
import com.hosever.core.model.OrderBy;
import com.hosever.core.model.Page;
import com.hosever.core.model.PageRequest;
import com.hosever.utils.OrderByUtils;

@Repository
public abstract class AbstractDaoImpl<E,ID extends Serializable> implements AbstractDao<E>{
	
	@Autowired
	protected HibernateTemplate hibernateTemplate;
	
	private String systemName = "hosever";
	
	private static Logger logger = Logger.getLogger(AbstractDaoImpl.class);  
	
	private Class<E> entityClass = null;
	private String className = "";
	
	
	@SuppressWarnings("unchecked")
	public AbstractDaoImpl() {
		entityClass = (Class<E>) ((ParameterizedType) getClass()
	            .getGenericSuperclass()).getActualTypeArguments()[0];
		className = entityClass.getName();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<E> list() {
		OrderBy orderBy = new OrderBy("createDate",OrderByUtils.ORDER_TYPE_DESC);
		String hql = "from "+ className + orderBy.getOrderSQL();
		logger.debug(systemName+"-Debug:查询列表"+className);
		List<?> result = hibernateTemplate.find(hql);
		return (List<E>)result;
	}
	
	@Override
	public Page<E> page(PageRequest pageRequest){
		if(pageRequest==null){
			return null;
		}
		
		OrderBy orderBy = new OrderBy("createDate",OrderByUtils.ORDER_TYPE_DESC);
		final String hql = "from "+ className + orderBy.getOrderSQL();
		
		logger.debug(systemName+"-Debug:分页查询"+className);
		List<E>  result = getListForPage(hql, pageRequest.getStart(), pageRequest.getPageSize());
		
		String countHql = "select count(*)  from "+ className + orderBy.getOrderSQL();
		List<Object> countResult = hibernateTemplate.find(countHql);
		int count = 0;
		if(!countResult.isEmpty()){
			count = Integer.valueOf(String.valueOf(countResult.get(0)));
		}
		logger.debug(systemName+"-Debug:分页总条数"+count);
		
		Page<E> page = setPageInfo(pageRequest,result);
		page.setTotalSize(count);
		
		return page;
	}
	
	/**   
	* 使用hql 语句进行操作   
	  
	   * @param hql   
	* @param offset   
	* @param length   
	* @return List   
	*/    
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<E> getListForPage(final String hql, final int offset,     
	    final int length) {     
	   List<E> list = (List<E>) hibernateTemplate.executeFind(new HibernateCallback() {     
	    public Object doInHibernate(Session session)     
	      throws HibernateException, SQLException {     
	     Query query = session.createQuery(hql);     
	     query.setFirstResult(offset);     
	     query.setMaxResults(length);     
	     List<E> list = query.list();     
	     return list;     
	    }     
	   });     
	   return list;     
	}
	
	private Page<E> setPageInfo(PageRequest pageRequest,List<E> content){
		Page<E> page = new Page<E>();
		page.setContent(content);
		page.setCurrentPage(pageRequest.getCurrentPage());
		page.setPageSize(pageRequest.getPageSize());
		page.setTotalPage(pageRequest.getTotalPage());
		page.setTotalSize(pageRequest.getTotalSize());
		return page;
	}
	
	@SuppressWarnings({"unchecked" })
	@Override
	public E findById(String id) {
		String hql = "from "+className+" e where e.id = :id";
		logger.debug(systemName+"-Debug:查找"+className+" id:"+id);
		return (E) hibernateTemplate.findByNamedParam(hql,"id", id).get(0);
	}
	
	@SuppressWarnings("unchecked")
	public List<E> findByIds(Collection<E> id){
		String hql = "from "+className+" e where e.id in (:id)"; 
		return (List<E>) hibernateTemplate.findByNamedParam(hql,"id", id);
	}

	@Override
	public boolean save(E e) {
		if(e==null){
			return false;
		}
		hibernateTemplate.save(e);
		logger.debug(systemName+"-Debug:保存"+e);
		return true;
	}

	@Override
	public boolean update(E e) {
		if(e==null){
			return false;
		}
		hibernateTemplate.update(e);
		logger.debug(systemName+"-Debug:更新"+e);
		return true;
	}

	@Override
	public boolean del(E e) {
		if(e==null){
			return false;
		}
		hibernateTemplate.delete(e);
		logger.debug(systemName+"-Debug:物理删除"+e);
		return true;
	}
   
//	@SuppressWarnings("unchecked")
//	public List<E> getListForPage(final String hql, final int offset, final int length){  
//        List<E> list = (List<E>)this.hibernateTemplate.executeFind(new HibernateCallback(){  
//            public Object doInHibernate(Session session) throws HibernateException, SQLException {  
//                Query query = session.createQuery(hql);  
//                query.setFirstResult(offset);  
//                query.setMaxResults(length);  
//                List list = query.list();  
//                return list;  
//            }  
//        });  
//        return list;  
//    } 

	@SuppressWarnings("unchecked")
	@Override
	public E customQuerySingle(String hql) {
		List<E> objects = (List<E>) hibernateTemplate.find(hql);
		logger.debug(systemName+"-Debug:查找单个"+className);
		return objects.get(0);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<E> customQuery(String hql) {
		logger.debug(systemName+"-Debug:查找多个"+className);
		return (List<E>) hibernateTemplate.find(hql);
	}
	
}
